package cn.jjxx.modules.sys.service.impl;

import cn.jjxx.core.common.entity.ZtreeEntity;
import cn.jjxx.core.common.service.impl.TreeCommonServiceImpl;
import cn.jjxx.core.query.wrapper.EntityWrapper;
import cn.jjxx.core.utils.ObjectUtils;
import cn.jjxx.core.utils.SpringContextHolder;
import cn.jjxx.core.utils.StringUtils;
import cn.jjxx.modules.sys.controller.MenuController;
import cn.jjxx.modules.sys.entity.Menu;
import cn.jjxx.modules.sys.entity.Organization;
import cn.jjxx.modules.sys.mapper.OrganizationMapper;
import cn.jjxx.modules.sys.service.IOrganizationService;
import cn.jjxx.modules.sys.utils.UserUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Transactional
@Service("organizationService")
public class OrganizationServiceImpl extends TreeCommonServiceImpl<OrganizationMapper, Organization, String>
		implements IOrganizationService {
	@Autowired
	private OrganizationMapper organizationMapper;
	
	@Override
	public List<Organization> findListByUserId(String userid) {
		return baseMapper.findListByUserId(userid);
	}

	@Override
	public List<Organization> findsubById(String orgId) {
		return organizationMapper.findsubById(orgId);
	}

	@Override
	public List<Organization> selectWbsTreeList(
			EntityWrapper<Organization> entityWrapper) {
		// 保证有where字句
		entityWrapper.eq("1", "1");
		return organizationMapper.selectWbsTreeList(entityWrapper);
	}

	@Override
	public Organization getRecentlyParent(String orgId, List<String> types,
			boolean isLocal) {
		List<Organization> list = new ArrayList<Organization>();
		//获取当前节点的上级路径
		Organization org = this.selectById(orgId);
		if(ObjectUtils.isNullOrEmpty(org)){
			return new Organization();
		}
		String parentIds = org.getParentIds();
		list.add(org);
		if(StringUtils.isNotEmpty(parentIds)){
			List<String> ids = Arrays.asList(parentIds.split("/"));
			//获取包含类型的所有组织
			EntityWrapper<Organization> wrapper = new EntityWrapper<Organization>(Organization.class);
			wrapper.in("id", ids);
			wrapper.orderBy("code",false);
			list.addAll(this.selectList(wrapper));
		}
		//取得最近距离的一条数据
		for(Organization o:list){
			if(getSpecifyTypeOrg(o, types)){
				return o;
			}
		}
		return new Organization();
	}

	@SuppressWarnings("null")
	@Override
	public List<Organization> getRecentlyChild(String orgId,
			List<String> types, boolean isLocal) {
		//获取当前节点的所有子节点
		List<Organization> orgs = new ArrayList<Organization>();
		List<Organization> list = baseMapper.getRecentlyChild(orgId, isLocal);
		if(list.size()>0){
			String parentIds = list.get(0).getParentIds();
			int index = parentIds==null?0:parentIds.split("/").length;
			for(Organization org:list){
				int i = org.getParentIds()==null?0:org.getParentIds().split("/").length;
				if(index!=i){
					index = i;
				}
				if(index==i){
					if(getSpecifyTypeOrg(org, types)){
						orgs.add(org);
					}
				}
			}
		}
		return orgs ;
	}
	
	/**
	 * @Description: 检测组织的控制类型是否包含某个list .<br>
	 * @param org 组织.<br>
	 * @param types 包含类型.<br>
	 * @author 郑成功 .<br>
	 * @date 2018-7-4 下午3:11:48.<br>
	 */
	private boolean getSpecifyTypeOrg(Organization org,List<String> types){
		String orgType = org.getOrgType();
		if(StringUtils.isNotEmpty(orgType)){
			List<String> list = new ArrayList<String>(Arrays.asList(orgType.split(",")));
			if(list.containsAll(types)){
				return true;
			}
		}
		return false;
	}

	@Override
	public List<ZtreeEntity> getOrgTree() {
		return getOrgTree(this.selectTreeList(new EntityWrapper<Organization>(Organization.class)));
	}

	@Override
	public List<ZtreeEntity> getOrgTree(List<Organization> orgs) {
		List<ZtreeEntity> list = new ArrayList<ZtreeEntity>();
		for(Organization org:orgs){
			ZtreeEntity ztree = new ZtreeEntity();
    		ztree.setId(org.getId());
    		ztree.setTitle(org.getName());
    		ztree.setName(org.getName());
    		ztree.setPid(org.getParentId());
    		ztree.setOpen(false);
    		ztree.setIsParent(org.isHasChildren());
    		list.add(ztree);
		}
		return list;
	}

	@Override
	public List<Organization> getPermisOrgs(String menuId) {
		List<String> orgIds = getOrgIds(menuId);
		List<String> permisOrgIds = UserUtils.getOrgChilds(true, true);
		EntityWrapper<Organization> wrapper = new EntityWrapper<Organization>(Organization.class);
		wrapper.setTableAlias("t.");
		wrapper.orderBy("code");
		orgIds.retainAll(permisOrgIds);
		HashSet<String> set = new HashSet<String>();
		set.addAll(orgIds);
		orgIds.addAll(set);
		wrapper.in("id", orgIds);
		List<Organization> list = this.selectTreeList(wrapper);
		//获取下级权限
		List<Organization> childrenList = getChildrenList(list, orgIds);
		for(Organization org:list){
			org.setHasChildren(hasChildren(org, childrenList));
		}
		return list;
	}
	
	@Override
	public List<Organization> getPermisOrgs(String[] types) {
		List<String> orgIds = getOrgIds(types);
		List<String> permisOrgIds = UserUtils.getOrgChilds(true, true);
		EntityWrapper<Organization> wrapper = new EntityWrapper<Organization>(Organization.class);
		wrapper.setTableAlias("t.");
		wrapper.orderBy("code");
		orgIds.retainAll(permisOrgIds);
		HashSet<String> set = new HashSet<String>();
		set.addAll(orgIds);
		orgIds.addAll(set);
		wrapper.in("id", orgIds);
		List<Organization> list = this.selectTreeList(wrapper);
		//获取下级权限
		List<Organization> childrenList = getChildrenList(list, orgIds);
		for(Organization org:list){
			org.setHasChildren(hasChildren(org, childrenList));
		}
		return list;
	}
	
	@Override
	public List<String> getOrgIds(String menuId){
		EntityWrapper<Organization> wrapper = new EntityWrapper<Organization>(Organization.class);
		List<String> orgIds = new ArrayList<String>();
		List<Organization> orgList = new ArrayList<Organization>();
		if(StringUtils.isNotEmpty(menuId)){
			Menu menu = SpringContextHolder.getBean(MenuController.class).get(menuId);
			String type = menu.getType();
			if(StringUtils.isNotEmpty(type)){
				List<String> str = Arrays.asList(type.split(","));
				for(String s:str){
					wrapper.or(" FIND_IN_SET("+s+",org_type)");
				}
				orgList = this.selectList(wrapper);
				//通过类型得到上级Id
			}
		}
		//获取所包含的组织
		for(Organization org:orgList){
			String parentIds = org.getParentIds();
			if(StringUtils.isNotEmpty(parentIds)){
				List<String> ids = Arrays.asList(parentIds.split("/"));
				for(String str:ids){
					orgIds.add(str);
				}
			}
			orgIds.add(org.getId());
		}
		return orgIds;
	}
	
	@Override
	public List<String> getOrgIds(String[] types){
		EntityWrapper<Organization> wrapper = new EntityWrapper<Organization>(Organization.class);
		List<Organization> orgList = new ArrayList<Organization>();
		List<String> orgIds = new ArrayList<String>();
		if(types!=null&&types.length>0){
			List<String> typesList = Arrays.asList(types);
			for(String type:typesList){
				wrapper.or(" FIND_IN_SET("+type+",org_type)");
			}
			orgList = this.selectList(wrapper);
			//获取所包含的组织
			for(Organization org:orgList){
				String parentIds = org.getParentIds();
				if(StringUtils.isNotEmpty(parentIds)){
					List<String> ids = Arrays.asList(parentIds.split("/"));
					for(String str:ids){
						orgIds.add(str);
					}
				}
				orgIds.add(org.getId());
			}
		}
		return orgIds;
	}
	
	@Override
	public List<Organization> getChildrenList(List<Organization> parentsList,List<String> permisOrgIds){
		List<String> ids = new ArrayList<String>();
		for(Organization org:parentsList){
			ids.add(org.getId());
		}
		EntityWrapper<Organization> wrapper = new EntityWrapper<Organization>(Organization.class);
		wrapper.setTableAlias("t.");
		wrapper.in("parent_id", ids);
		wrapper.in("id", permisOrgIds);
		return this.selectTreeList(wrapper);
	}
	
	
	@Override
	public boolean hasChildren(Organization parent,List<Organization> childrens){
		for(Organization child:childrens){
			if(StringUtils.isNotEmpty(child.getParentId())
					&&StringUtils.endsWith(parent.getId(), child.getParentId())){
				return true;
			}
		}
		return false;
	}

	@Override
	public Organization getOrganization(List<Organization> orgs, String id) {
		if(StringUtils.isNotEmpty(id)){
			for(Organization org:orgs){
				if(StringUtils.equals(id, org.getId())){
					return org;
				}
			}
		}
		return new Organization();
	}

}
